package com.nwu.custom_view.qq_step_view;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;

import androidx.annotation.Nullable;

import com.nwu.custom_view.R;

public class StepView extends View {

    private int outerColor;
    private int innerColor;
    private int borderWidth;
    private int stepTextColor;
    private int stepTextSize;

    private int currentStep;
    private int maxStep;

    private Paint outerPaint;
    private Paint innerPaint;
    private Paint textPaint;

    public StepView(Context context) {
        this(context, null);
    }

    public StepView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    @SuppressLint("ResourceAsColor")
    public StepView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        // 获得自定义属性
        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.StepView);
        outerColor = array.getColor(R.styleable.StepView_outer_color, R.color.yellow);
        innerColor = array.getColor(R.styleable.StepView_inner_color, R.color.deepskyblue);
        borderWidth = (int) array.getDimension(R.styleable.StepView_border_width, 35);
        stepTextColor = array.getColor(R.styleable.StepView_step_text_color, R.color.red);
        stepTextSize = array.getDimensionPixelSize(R.styleable.StepView_step_text_size, 60);
        // 当获取完TypedArray所有的属性值后，一般要调用recycle()方法来完成资源的回收，避免重新创建的时候的错误
        array.recycle();
        // 初始化外圆弧画笔
        outerPaint = new Paint();
        outerPaint.setAntiAlias(true); // 设置抗锯齿，保证边界不模糊
        outerPaint.setColor(outerColor);  // 设置颜色
        outerPaint.setStrokeWidth(borderWidth);   // 设置圆弧宽度
        outerPaint.setStyle(Paint.Style.STROKE);   // 设置圆弧不填充
        outerPaint.setStrokeCap(Paint.Cap.ROUND);  // 设置边角光滑（圆弧端点为圆形）
        // 初始化内圆弧画笔
        innerPaint = new Paint();
        innerPaint.setAntiAlias(true); // 设置抗锯齿
        innerPaint.setColor(innerColor);  // 设置颜色
        innerPaint.setStrokeWidth(borderWidth);   // 设置圆弧宽度
        innerPaint.setStyle(Paint.Style.STROKE);   // 设置圆弧不填充
        innerPaint.setStrokeCap(Paint.Cap.ROUND);  // 设置边角光滑（圆弧端点为圆形）
        // 初始化文字画笔
        textPaint = new Paint();
        textPaint.setAntiAlias(true);  // 设置抗锯齿
        textPaint.setColor(stepTextColor);    // 设置颜色
        textPaint.setTextSize(stepTextSize);  // 设置字体大小
        // 初始化文字矩形对象
        rect = new Rect();
        rectF = new RectF();
    }

    /**
     * 用于测量，控件占多大的地方由这个方法指定
     *
     * @param widthMeasureSpec
     * @param heightMeasureSpec
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // 调用者可能是wrap_content或match_parent、宽高可能不一致
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);
        // 由于计步器取正方形，所以取宽高的最小值，确保每一个子View是一个正方型
        setMeasuredDimension(Math.min(width, height), Math.min(width, height));
    }

    private float dx, baseLine;
    private Rect rect;
    private RectF rectF;

    /**
     * 绘制效果：外圆弧、内圆弧、文字
     * onDraw用于绘制，控件呈现给用户长什么样子由这个方法决定
     *
     * @param canvas 画布
     */
    @Override
    protected void onDraw(Canvas canvas) {
        // 绘制外圆弧，指定外圆弧轮廓的矩形区域 (left, top, right, bottom)
        rectF = new RectF(
                borderWidth / 2,
                borderWidth / 2,
                getWidth() - borderWidth / 2,
                getHeight() - borderWidth / 2);
        canvas.drawArc(rectF, 135, 270, false, outerPaint);
        // 根据比例绘制内圆弧（根据最大步数和当前步数计算比例）
        if (maxStep == 0) return;  // 最大步数为0，直接return避免除0
        float ratio = (float) currentStep / maxStep;  // 计算当前步数所占百分比
        // 从135度开始画圆弧，270度是整个圆弧度数，乘当前步数所占百分比，得到当前步数所占弧度
        canvas.drawArc(rectF, 135, 270 * ratio, false, innerPaint);
        // 获取字体宽度
        String text = String.valueOf(currentStep);
        rect = new Rect();
        // getTextBounds获得的是包裹当前字体的最小矩形
        textPaint.getTextBounds(text, 0, text.length(), rect);
        dx = getWidth() / 2 - rect.width() / 2;
        baseLine = getHeight() / 2 + rect.height() / 2; // 基线
        canvas.drawText(text, dx, baseLine, textPaint);
    }

    public void setMaxStep(int maxStep) {
        this.maxStep = maxStep;
    }

    public void setCurrentStep(int currentStep) {
        this.currentStep = currentStep;
        invalidate();   // 不断重绘
    }
}
